Skip to content

feat(novel-reader): render inline novel images with correct aspect ratio#122

Open
andrew05060414 wants to merge 14 commits intoalphasp:masterfrom
andrew05060414:codex/novel-inline-images-pr
Open

feat(novel-reader): render inline novel images with correct aspect ratio#122
andrew05060414 wants to merge 14 commits intoalphasp:masterfrom
andrew05060414:codex/novel-inline-images-pr

Conversation

@andrew05060414
Copy link
Copy Markdown

Summary

Pixiv novels support two types of inline images that are currently not rendered in the reader:

  • [uploadedimage:ID] — images uploaded specifically for a novel
  • [pixivimage:ID] — regular Pixiv illustrations embedded in novel text

This PR adds full support for both, fetching metadata and displaying each image inline at its correct aspect ratio.

Changes

Core image rendering

  • NovelInlineImage.js (new component): resolves image URLs and aspect ratios from embedded metadata or the Pixiv API; falls back to Image.getSizeWithHeaders (with Referer header so Pixiv CDN accepts the request), then to an onLoad native measurement as a final safety net
  • NovelViewer.js: renders <px-image> custom tags as NovelInlineImage components inline with novel text
  • novelTextParser.js: converts [uploadedimage:ID] / [loadedimage:ID] markers in novel text to <px-image> tags
  • novelInlineImage.js (new helper): tag builder and text-scanner for inline image markers
  • novelAjaxParser.js (new helper): extracts novel data (text, embedded images) from the Pixiv AJAX endpoint /ajax/novel/:id
  • novelWebviewParser.js (new helper): fallback parser that extracts the same data from the Pixiv webview HTML (__NEXT_DATA__, meta-preload-data, legacy state)
  • novelWebviewImageCandidates.js (new helper): scrapes originalUrl + dimensions for [uploadedimage] entries from raw HTML when the API response lacks them
  • novelText.js saga: tries the AJAX endpoint first; falls back to webview HTML; merges textEmbeddedImages with scraped candidates before dispatching success

Login flow stability

  • PXWebView.js: intercepts intent:// deep-links and forwards them via Linking.openURL so the Pixiv OAuth redirect works on Android; adds setSupportMultipleWindows={false}
  • pkce.js: persists the PKCE verifier in AsyncStorage so it survives the OAuth round-trip if the in-memory value is lost
  • Login.js: awaits the now-async PKCE.getPKCE() call

Test plan

  • Open a Pixiv novel that contains [uploadedimage:ID] markers — images should appear inline at their original aspect ratio (not cropped to square)
  • Open a Pixiv novel that contains [pixivimage:ID] markers — illustrations should appear inline
  • Novels with no inline images should render identically to before
  • Login / re-login flow should complete successfully on Android

🤖 Generated with Claude Code

andrew05060414 and others added 14 commits April 1, 2026 01:12
Image aspect ratio:
- Replace Image.getSize() with Image.getSizeWithHeaders() passing Referer
  header so Pixiv CDN accepts the request and returns real dimensions
- Add onLoad handler on PXImage as fallback: reads nativeEvent.source
  width/height once the image actually loads

Login flow (PXWebView + PKCE):
- Handle intent:// deep-links in PXWebView.onShouldStartLoadWithRequest
  so Pixiv OAuth redirects open correctly on Android
- Add setSupportMultipleWindows={false} to prevent unwanted tab opens
- Persist PKCE verifier to AsyncStorage so it survives the OAuth round-trip
- Fix Login.js to await async PKCE.getPKCE() call

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…incomplete

Parse nested ajax novel payloads and merge embedded image candidates from ajax/webview/html so uploadedimage markers no longer fall back to Image unavailable diagnostics.

Made-with: Cursor
Split reader navigation positioning into two independent settings so users can choose slider and percentage badge sides separately in both global and in-reader settings.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant